#include "ProtectionTrip.h"
#include "..\System\F2806x_Device.h"
#include "..\System\F2806x_EPwm_defines.h"

#define TRIPLEVEL 700

void ProtectionTrip::Init(void)
{
	EALLOW;

	// Enable and set COMP (analog comparator) modules
	//SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;     // Enable Clock to the ADC --> already enabled in in _sysctrl.c
	//SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1;   // Enable clock to the Comparator 1 block	--> already enabled in in _sysctrl.c
	//SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 1;   // Enable clock to the Comparator 2 block	--> already enabled in in _sysctrl.c
	//SysCtrlRegs.PCLKCR3.bit.COMP3ENCLK = 1;   // Enable clock to the Comparator 3 block	--> already enabled in in _sysctrl.c
	//AdcRegs.ADCCTL1.bit.ADCBGPWD = 1;         // Comparator shares the internal BG reference of the ADC, must be powered even if ADC is unused
	//DELAY_US(10000);							// Delay for Power Up --> already enabled in _xileg_vdc

	// Doesn't work due to large switching noise (~5us, max current)
	/*
	Comp1Regs.COMPCTL.bit.COMPDACEN = 1;        // Power up Comparator 1 locally
	Comp1Regs.COMPCTL.bit.COMPSOURCE = 0;       // Connect the inverting input to the internal DAC
	Comp1Regs.DACVAL.bit.DACVAL = TRIPLEVEL;	// Set DAC output to TRIPLEVEL

	Comp2Regs.COMPCTL.bit.COMPDACEN = 1;        // Power up Comparator 2 locally
	Comp2Regs.COMPCTL.bit.COMPSOURCE = 0;       // Connect the inverting input to the internal DAC
	Comp2Regs.DACVAL.bit.DACVAL = TRIPLEVEL;	// Set DAC output to TRIPLEVEL

	Comp3Regs.COMPCTL.bit.COMPDACEN = 1;        // Power up Comparator 3 locally
	Comp3Regs.COMPCTL.bit.COMPSOURCE = 0;       // Connect the inverting input to the internal DAC
	Comp3Regs.DACVAL.bit.DACVAL = TRIPLEVEL;	// Set DAC output to TRIPLEVEL

	//ePWM1 (PHASE-B, COMP2)
	// Define an event (DCAEVT1)
	EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP2OUT;        // DCAH = Comparator 2 output
	EPwm1Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI;              // DCAEVT1 =  DCAH high(will become active as Comparator output goes high)
	EPwm1Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1;                // DCAEVT1 = DCAEVT1 (not filtered)
	EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC;       // Take async path
	EPwm1Regs.TZSEL.bit.DCAEVT1 = 1; // DEFINE AS ONE SHOT! (will be cleared with OST)

	// another source (use comparator B)
	//EPwm1Regs.DCTRIPSEL.bit.DCBHCOMPSEL = DC_COMP1OUT;        // DCBH = Comparator 2 output
	//EPwm1Regs.TZDCSEL.bit.DCBEVT1 = TZ_DCBH_HI;              // DCBEVT1 =  (will become active as Comparator output goes high)
	//EPwm1Regs.DCBCTL.bit.EVT1SRCSEL = DC_EVT1;                // DCBEVT1 = DCBEVT1 (not filtered)
	//EPwm1Regs.DCBCTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC;       // Take async path
	//EPwm1Regs.TZSEL.bit.DCBEVT1 = 1;

	//ePWM2 (PHASE-A, COMP3)
	// Define an event (DCAEVT1)
	EPwm2Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP3OUT;        // DCAH = Comparator 3 output
	EPwm2Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI;              // DCAEVT1 =  DCAH high(will become active as Comparator output goes high)
	EPwm2Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1;                // DCAEVT1 = DCAEVT1 (not filtered)
	EPwm2Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC;       // Take async path
	EPwm2Regs.TZSEL.bit.DCAEVT1 = 1; // DCAEVT1 is one shot trip source

	//ePWM3 (PHASE-C, COMP1)
	// Define an event (DCAEVT1)
	EPwm3Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP1OUT;        // DCAH = Comparator 1 output
	EPwm3Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI;              // DCAEVT1 =  DCAH high(will become active as Comparator output goes high)
	EPwm3Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1;                // DCAEVT1 = DCAEVT1 (not filtered)
	EPwm3Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC;       // Take async path
	EPwm3Regs.TZSEL.bit.DCAEVT1 = 1; // DCAEVT1 is one shot trip source
*/

	// actions
	// What do we want the DCAEVT1 and DCBEVT1 events to do?
	// DCAEVTx events can force EPWMxA
	// DCBEVTx events can force EPWMxB
	EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;           // EPWM1A will go low
	EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;           // EPWM1B will go low
	EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO;           // EPWM2A will go low
	EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO;           // EPWM2B will go low
	EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO;           // EPWM2A will go low
	EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_LO;           // EPWM2B will go low

	EDIS;
}

void ProtectionTrip::ProcessTrips(void)
{
	// check for trips
	if( EPwm1Regs.TZFLG.bit.OST == 0x1 || EPwm2Regs.TZFLG.bit.OST == 0x1 || EPwm3Regs.TZFLG.bit.OST == 0x1)
	{
		// trip all now!
		KillAll();
	}
}

bool ProtectionTrip::IsTripped(void)
{
	if( EPwm1Regs.TZFLG.bit.OST == 0x1 || EPwm2Regs.TZFLG.bit.OST == 0x1 || EPwm3Regs.TZFLG.bit.OST == 0x1) return true;

	return false;
}

void ProtectionTrip::KillAll(void)
{
	EALLOW;
	EPwm1Regs.TZFRC.bit.OST = 0x1;
	EPwm2Regs.TZFRC.bit.OST = 0x1;
	EPwm3Regs.TZFRC.bit.OST = 0x1;
	EDIS;
}

void ProtectionTrip::ClearTrips(void)
{
	EALLOW;
	EPwm1Regs.TZCLR.bit.OST = 0x1;
	EPwm2Regs.TZCLR.bit.OST = 0x1;
	EPwm3Regs.TZCLR.bit.OST = 0x1;
	EDIS;
}
